package umlTransfo;


import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.ui.internal.ide.model.ResourceFactory;
import org.eclipse.uml2.uml.AggregationKind;
import org.eclipse.uml2.uml.Association;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Enumeration;
import org.eclipse.uml2.uml.EnumerationLiteral;
import org.eclipse.uml2.uml.Generalization;
import org.eclipse.uml2.uml.LiteralUnlimitedNatural;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.PrimitiveType;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLFactory;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.resource.UMLResource;

import EmportImportDMTFCIM.ClassCIM;

public class CIMtoUML {
	private ClassCIM classCIM;
	public CIMtoUML(ClassCIM classCIM, java.net.URI uri) {
		
		this.classCIM = classCIM;
		
		Model model = CIMtoUML.createModel(classCIM.getName());
		Package package_= CIMtoUML.createPackage(model.getNearestPackage(), "Root Package");
		org.eclipse.uml2.uml.Class ClassUML= CIMtoUML.createClass(package_, classCIM.getName(), false);
		HashMap<String, String> attributes = classCIM.getAttributes();
		Type typeprimitif;
		for (String mapKey : attributes.keySet()) {
			typeprimitif = CIMtoUML.createPrimitiveType(package_, attributes.get(mapKey));
			CIMtoUML.createAttribute(ClassUML, mapKey, typeprimitif, 0, 1);
		}
		//operations
		HashMap<String, String> operations = classCIM.getOperations();
		HashMap<String, String> returnOp = classCIM.getOperationsReturnTypes();
		PrimitiveType return_type = CIMtoUML.createPrimitiveType(package_, "void");
		System.out.println("taille" + operations.size());
		for (String mapKey : operations.keySet()) {
			CIMtoUML.createOperation(ClassUML, mapKey, return_type);
		}
		

		save(model,URI.createURI(uri.toString()).appendSegment(this.classCIM.getName()).appendFileExtension(UMLResource.FILE_EXTENSION)); 

	}

	protected static Model createModel(String name) {
        Model model = UMLFactory.eINSTANCE.createModel();
        model.setName(name);

        System.out.println("Model '" + model.getQualifiedName() + "' created.");

        return model;
    }
	
	protected static Package createPackage(Package nestingPackage, String name) {
       Package package_ = nestingPackage.createNestedPackage(name);

        System.out.println("Package '" + package_.getQualifiedName() + "' created.");

        return package_;
    }
	
	 protected static PrimitiveType createPrimitiveType(org.eclipse.uml2.uml.Package package_, String name) {
         PrimitiveType primitiveType = (PrimitiveType) package_.createOwnedPrimitiveType(name);
 
         System.out.println("Primitive type '" + primitiveType.getQualifiedName() + "' created.");
 
         return primitiveType;
     }
	 
	 protected static Enumeration createEnumeration(org.eclipse.uml2.uml.Package package_, String name) {
         Enumeration enumeration = (Enumeration) package_.createOwnedEnumeration(name);
 
         System.out.println("Enumeration '" + enumeration.getQualifiedName() + "' created.");
 
         return enumeration;
     }
	 
	 protected static EnumerationLiteral createEnumerationLiteral(Enumeration enumeration, String name) {
         EnumerationLiteral enumerationLiteral = enumeration.createOwnedLiteral(name);
 
         System.out.println("Enumeration literal '" + enumerationLiteral.getQualifiedName() + "' created.");
 
         return enumerationLiteral;
     }
	 
	 protected static org.eclipse.uml2.uml.Class createClass(org.eclipse.uml2.uml.Package package_, String name, boolean isAbstract) {
         org.eclipse.uml2.uml.Class class_ = package_.createOwnedClass(name, isAbstract);
 
         System.out.println("Class '" + class_.getQualifiedName() + "' created.");
 
         return class_;
     }
	 protected static Generalization createGeneralization(Classifier specificClassifier, Classifier generalClassifier) {
         Generalization generalization = specificClassifier.createGeneralization(generalClassifier);
 
         System.out.println("Generalization " + specificClassifier.getQualifiedName() + " ->> " + generalClassifier.getQualifiedName() + " created.");
 
         return generalization;
     
	 }
	  protected static Property createAttribute(org.eclipse.uml2.uml.Class class_, String name, Type type, int lowerBound, int upperBound) {
	         Property attribute = class_.createOwnedAttribute(name, type, lowerBound, upperBound);
	 
	         StringBuffer sb = new StringBuffer();
	 
	         sb.append("Attribute '");
	 
	         sb.append(attribute.getQualifiedName());
	 
	         sb.append("' : ");
	 
	         sb.append(type.getQualifiedName());
	 
	         sb.append(" [");
	         sb.append(lowerBound);
	         sb.append("..");
	         sb.append(LiteralUnlimitedNatural.UNLIMITED == upperBound ? "*" : String.valueOf(upperBound));
	         sb.append("]");
	 
	         sb.append(" created.");
	 
	         System.out.println(sb.toString());
	 
	         return attribute;
	     }
	  

	  protected static Operation createOperation(org.eclipse.uml2.uml.Class class_, String name, Type return_type) {
	         //Property attribute = class_.createOwnedAttribute(name, type, lowerBound, upperBound);
	          Operation op = class_.createOwnedOperation(name, null, null, return_type);
	         return op;
	     }
	  protected static Association createAssociation(Type type1, boolean end1IsNavigable, AggregationKind end1Aggregation,
	             String end1Name, int end1LowerBound, int end1UpperBound,
	             Type type2, boolean end2IsNavigable, AggregationKind end2Aggregation,
	             String end2Name, int end2LowerBound, int end2UpperBound) {
	 
	         Association association = type1.createAssociation(end1IsNavigable, end1Aggregation, end1Name, end1LowerBound, end1UpperBound,
	             type2, end2IsNavigable, end2Aggregation, end2Name, end2LowerBound, end2UpperBound);
	 
	         StringBuffer sb = new StringBuffer();
	 
	         sb.append("Association ");
	 
	         if (null == end1Name || 0 == end1Name.length()) {
	             sb.append('{');
	             sb.append(type1.getQualifiedName());
	             sb.append('}');
	         } else {
	             sb.append("'");
	             sb.append(type1.getQualifiedName());
	             sb.append(NamedElement.SEPARATOR);
	             sb.append(end1Name);
	             sb.append("'");
	         }
	 
	         sb.append(" [");
	         sb.append(end1LowerBound);
	         sb.append("..");
	         sb.append(LiteralUnlimitedNatural.UNLIMITED == end1UpperBound ? "*" : String.valueOf(end1UpperBound));
	         sb.append("] ");
	 
	         sb.append(end2IsNavigable ? '<' : '-');
	         sb.append('-');
	         sb.append(end1IsNavigable ? '>' : '-');
	         sb.append(' ');
	 
	         if (null == end2Name || 0 == end2Name.length()) {
	             sb.append('{');
	             sb.append(type2.getQualifiedName());
	             sb.append('}');
	         } else {
	             sb.append("'");
	             sb.append(type2.getQualifiedName());
	             sb.append(NamedElement.SEPARATOR);
	             sb.append(end2Name);
	             sb.append("'");
	         }
	 
	         sb.append(" [");
	         sb.append(end2LowerBound);
	         sb.append("..");
	         sb.append(LiteralUnlimitedNatural.UNLIMITED == end2UpperBound ? "*" : String.valueOf(end2UpperBound));
	         sb.append("]");
	 
	         sb.append(" created.");
	 
	         System.out.println(sb.toString());
	 
	         return association;
	     }
	  
	     protected static void save(org.eclipse.uml2.uml.Package package_, org.eclipse.emf.common.util.URI uri) {
	      
	    	 Resource resource = new ResourceSetImpl().createResource(uri);
	         resource.getContents().add(package_);
	 
	         try {
	             resource.save(null);
	             System.out.println("Done.");
	         } catch (IOException ioe) {
	        	  System.out.println(ioe.getMessage());
	         }
	         
	     }
}
